<template>
  <div class="container">
    <el-upload
      ref="uploadRef"
      class="upload-file"
      :name="name"
      :data="data"
      :headers="headers"
      :action="uploadApi"
      :limit="limit"
      accept=".xls, .xlsx, .jpg,.jpeg, .png, .pdf, .doc, .docx, .zip, .rar"
      :show-file-list="false"
      :file-list="fileList"
      :on-exceed="handleExceed"
      :on-change="handleChange"
      :on-error="handleUploadError"
      :on-progress="handleProgress"
      :on-success="handleUploadSuccess"
      :before-upload="handleBeforeUpload"
    >
      <el-button
        v-if="fileList.length<limit&&showUpload===true"
        size="small"
        :type="uploadPercentage?'warning':'primary'"
        class="btn-upload"
      >
        {{ uploadPercentage?'正在导入数据，请耐心等待...':'点击导入文件' }}
      </el-button>
      <!-- <div v-if="fileList.length">
      <strong>以下文件已导入成功</strong>
    </div> -->
      <ul
        v-show="fileList.length"
        class="file-item el-upload-list el-upload-list--text draglistmove"
        @click="maskClick"
      >
        <li v-for="(file,index) in fileList" :key="file.id" class="el-upload-list__item is-success li-flex-box">
          <a v-show="file.id !== showEditItem" class="el-upload-list__item-name">
            <i class="el-icon-document " /> {{ file.attachmentName }}
          </a>
          <!-- <span v-show="!file.showEdit" class="file-name">{{ file.name }}</span> -->

          <a v-show="file.id ===showEditItem" class="el-upload-list__item-name">
            <el-input v-model="file.attachmentName" autofocus size="mini" @change="saveEdit(file)" />
          </a>

          <span class="option-box">
            <span
              v-show="showRemove"
              class="option-icon"
              @click="handleBeforeRemove(file,index)"
            >
              <i class="el-icon-delete" />
            </span>
            <span
              v-show="showEdit"
              class="option-icon"
              @click="handleEdit(file)"
            >
              <i class="el-icon-edit" />
            </span>
            <!-- 所有文件可直接下载 -->
            <a
              class="option-icon link-item"
              :href="url+'/'+file.attachmentUrl"
              :download="file.attachmentName"
            >
              <i class="el-icon-download" />
            </a>
            <span
              class="option-icon"
              @click="handlePreview(file)"
            >
              <i class="el-icon-zoom-in" />
            </span>
          </span> </li>
      </ul>
      <div v-show="!fileList.length&&showUpload===true" slot="tip" class="el-upload__tip">文件大小不超过{{ fileSize / 1024 /1024 }} M</div>
      <div v-if="uploadPercentage" class="mask-upload" @click="maskClick">
        <el-progress
          :percentage="uploadPercentage"
          :status="uploadStatus"
        />
        <div class="btn-cancel">
          <span v-if="cancelStatus" @click.stop="cancelUploadFile"><i class="el-icon-close" /></span>
          <span v-if="clearStatus" @click.stop="clearUploadStatus"><i class="el-icon-close" /></span>
        </div>
      </div>
    </el-upload>
    <!-- 图片预览 -->
    <el-dialog
      :visible.sync="imgDialogVisible"
      width="400px"
      :before-close="handleCloseImg"
    >
      <el-image :src="previewImg | filterURL" />
    </el-dialog>
  </div>
</template>

<script>
import Sortable from 'sortablejs'
import { getToken } from '@/utils/auth'
export default {
  name: 'FileUploader',
  props: {
    data: {
      type: Array,
      default: () => {
        return []
      }
    },
    showUpload: {
      type: Boolean,
      default: true
    },
    showEdit: {
      type: Boolean,
      default: true
    },
    showRemove: {
      type: Boolean,
      default: true
    },
    showDownload: {
      type: Boolean,
      default: true
    },
    action: {
      type: String,
      default: () => `/ads-admin/api/v1/adsEnclosureInfo/uploadFile` // 附件默认上传路径
    },
    name: {
      type: String,
      default: 'file'
    },
    limit: {
      type: Number,
      default: 1
    },
    fileSize: {
      type: Number,
      default: 1024 * 1024 * 200
    },
    beforeUpload: {
      type: Function,
      default: function() {
        return true
      }
    },
    beforeRemove: {
      type: Function,
      default: function() {
        return true
      }
    }
  },
  inject: {
    // 获取父组件的provide
    elForm: {
      default: ''
    },
    elFormItem: {
      default: ''
    }
  },
  data() {
    return {
      previewImg: '', // 图片预览
      imgDialogVisible: false,
      showEditItem: '',
      url: `/pdf-file/`,
      loadFlag: false,
      headers: {
        // 文件上传请求头
        'X-Token': this.$store.getters.token ? getToken() : '',
        'Authorization': this.$store.getters.token ? 'Bearer ' + getToken() : ''
      },
      fileList: [],
      cancelStatus: false, // 是否需要取消上传
      clearStatus: false, // 是否可以清除组件上传状态
      uploadPercentage: 0, // 上传百分比
      uploadStatus: '' // 上传是否失败，失败时会设置为 exception
    }
  },
  computed: {
    uploadApi() {
      return this.action
    }
  },
  created() {
    this.fileList = this.data
    this.fileList.forEach(el => {
      this.$set(el, 'showEdit', false)
    })
  },
  mounted() {
    this.listmove()
  },
  methods: {
    // 关闭图片预览
    handleCloseImg() {
      this.imgDialogVisible = false
    },
    // 拖拽排序功能
    listmove() {
      const el = document.querySelector('.draglistmove')
      Sortable.create(el, {
        onEnd: e => {
          const s = e.newIndex
          const o = e.oldIndex
          setTimeout(() => {
            const data = this.fileList[s]
            this.fileList[s] = this.fileList[o]
            this.fileList[o] = data
            this.$emit('upload-success', { file: {}, list: this.fileList })
          }, 100)
        }
      })
    },
    handleEdit(file) {
      if (this.showEditItem === file.id) {
        this.showEditItem = ''
      } else {
        this.showEditItem = file.id
      }
      // file.showEdit = !file.showEdit
    },
    saveEdit(file) {
      this.showEditItem = ''
      // file.showEdit = !file.showEdit
      this.$emit('upload-success', { file: file, list: this.fileList })
    },

    handlePreview(file) {
      // if (file.type !== 'pdf' || file.type !== 'word' || file.type !== 'excel') {
      //   this.$message.warning('该文件类型不支持预览')
      //   return
      // }
      if (file.typeName === 'pdf') {
        // pdf预览
        const url = this.url + file.attachmentUrl
        const routeData = this.$router.resolve({
          path: '/viewFile',
          query: {
            src: btoa(url)
          }
        })
        window.open(routeData.href, '_blank')
      } else if (file.typeName === 'jpg' || file.typeName === 'jpeg' || file.typeName === 'png') {
      // 图片预览
        this.imgDialogVisible = true
        this.previewImg = file.attachmentUrl
      } else if (file.typeName === 'doc' || file.typeName === 'docx') {
        window.open(`${process.env.VUE_APP_OFFICE_PREFIX}?src=` + process.env.VUE_APP_IMG_PREFIX + file.attachmentUrl)
      } else {
        this.$message.warning('该文件类型不支持预览')
      }
    },
    handleBeforeUpload: function(file) {
      this.loadFlag = true
      // 上传前校验
      // const accept = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
      // var isExcel = accept.includes(file.type)
      var isLt2M = file.size < this.fileSize
      // if (!isExcel) {
      //   this.$message.error('只能上传EXCEL文件!')
      // }
      if (!isLt2M) {
        this.$message.error('上传文件大小不能超过 ' + (this.fileSize / 1024 / 1024) + 'M!')
      }
      if (isLt2M) {
        return this.beforeUpload(file)
      } else {
        return false
      }
    },
    handleProgress(event, file) {
      this.cancelStatus = true // 展示中断按钮
      // 上传中 event.percent 百分比
      this.uploadStatus = '' // 上传状态置空,
      this.uploadPercentage = parseFloat(event.percent.toFixed(1))
      if (this.uploadPercentage > 99) {
        this.uploadPercentage = 99.0
      }
    },
    handleUploadSuccess(response, file) {
      this.cancelStatus = false // 隐藏取消按钮
      this.loadFlag = false
      // 上传成功回调
      if (response.success === 1) {
        this.uploadPercentage = 0// 上传进度归零, 隐藏进度框
        const fileData = {
          attachmentUrl: (response.data && response.data.enclosurePath) || '', // 文件路径
          remark: (response && response.msg) || '', // 备注
          attachmentName: (response.data && response.data.enclosureName) || '', // 文件名
          id: (response.data && response.data.id) || '', // id
          typeName: (response.data && response.data.enclosureType) || '', // 附件类型

          configAttachmentId: (response.data && response.data.id) || '', // 附件模板配置id todo
          modelId: (response.data && response.data.id) || '', // 附件模板配置id todo
          attachmentType: (response.data && response.data.enclosureType) || ''// 附件类型 todo
        }
        this.fileList.push(fileData)
        this.$emit('upload-success', { file: fileData, list: this.fileList })
      } else {
        if (response.code === 401 || response.code === '401' || response.status === 401) {
          this.refreshToken({}, () => {
            this.refreshHeaders()
          })
        } else {
          this.uploadStatus = 'exception'
          this.$message.error('上传失败: ' + response.msg)
          this.clearStatus = true
        }
        this.$refs.uploadRef.clearFiles()
      }
      this.$emit('upload-finish', response)
    },
    handleUploadError(err, file) {
      this.loadFlag = false
      // 上传失败
      const res = JSON.parse(JSON.stringify(err))
      if (res.code === 401 || res.code === '401' || res.status === 401) {
        this.refreshToken({}, () => {
          this.refreshHeaders()
        })
      } else {
        this.$message.error('上传失败: ' + err)
        this.uploadStatus = 'exception'
        this.clearStatus = true
      }
      this.$refs.uploadRef.clearFiles()
    },
    handleChange(file) {
      this.$emit('on-change', '')
    },
    handleExceed(files, fileList) {
      this.$message.warning(`最多只能上传 ${this.limit} 个文件`)
    },
    clearUploadFile() {
      this.uploadStatus = ''
      this.uploadPercentage = 0
      this.cancelStatus = false
      this.clearStatus = false
      this.$refs.uploadRef.clearFiles()
    },
    /**
       *@methods:clearUploadStatus
       *@description: 当上传失败时清空上传组件里面的状态值
       **/
    clearUploadStatus() {
      this.uploadPercentage = 0
      this.clearStatus = false
      this.clearUploadFile()
    },
    /**
       *@methods:cancelUploadFile
       *@description:点击取消按钮 触发中断事件
       **/
    cancelUploadFile() {
      this.$refs.uploadRef.abort()
      this.uploadPercentage = 0
      this.$message({
        type: 'success',
        message: '上传已中断,请重新上传文件'
      })
      this.clearUploadFile()
    },
    maskClick(event) {
      // 阻止默认的文件弹出框
      event.stopImmediatePropagation()
    },
    handleBeforeRemove(file) {
      const before = this.beforeRemove()
      if (before && before.then) {
        before.then(() => {
          this.onRemove(file)
        })
      } else if (before !== false) {
        this.onRemove(file)
      }
    },
    onRemove(file) {
      const index = this.fileList.findIndex(v => v.id === file.id)
      if (index > -1) {
        this.fileList.splice(index, 1)
      }
      this.$emit('remove', { file: file, list: this.fileList })
    },
    refreshHeaders() {
      this.headers = {
        'X-Token': this.$store.getters.token ? getToken() : '',
        'Authorization': this.$store.getters.token ? 'Bearer ' + getToken() : ''
      }
    }
  }
}
</script>

<style lang='scss' scoped>
.container{
  min-height: 150px;
}
.li-flex-box{
  width: 400px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.file-item{

}
  .upload-file{
    position: relative;
    line-height: 30px;
    /deep/.el-upload{
      width: 100%;
      text-align: left;
    }
    .btn-upload{
      margin-bottom: 10px;
    }
  }
  .mask-upload{
    position: absolute;
    left: 0;
    top: 0;
    right:0;
    bottom:0;
    background: rgba($color: #000000, $alpha: 0);
    text-align: center;
    padding-top: 35px;
    padding-right:35px;
    width: 370px;
    .btn-cancel{
      position: absolute;
      right: 10px;
      top: 25px;
    }
  }
  .el-upload-list__item:hover {
    background-color: #F5F7FA;
    .option-box{
      display:block;
      color: $--color-primary;
      cursor: pointer;
  }
}
   .option-box{
     display: none;
    .option-icon{
      padding: 0 10px;
    }
    .link-item{
      color: $--color-primary;
    }
  }
/deep/.el-upload-list__item.is-success .el-upload-list__item-status-label {
    display: none;
}
/deep/.el-upload-list__item:hover .el-icon-close{
  display: none;
}
.file-name{
    width: 200px;
    font-size: 12px;
  }
</style>
